#include <ean13.hpp>

#include <boost/test/minimal.hpp>

#include <country_code.hpp>

void test_binary_symmetry( const barcode::ean13& ean13_ )
{
	barcode::ean13_binary ean13_binary_( ean13_ );

	barcode::ean13 ean13_restored_ = from_binary( ean13_binary_ );
	BOOST_CHECK( ean13_restored_ == ean13_ );
}

template < typename ByteInputIterator >
void test_data_restore( ByteInputIterator data_begin_
							  , ByteInputIterator data_end_
							  , const barcode::ean13& expected_ean13_ )
{
	barcode::ean13_binary ean13_binary_( data_begin_, data_end_ );

	barcode::ean13 ean13_restored_ = from_binary( ean13_binary_ );
	BOOST_CHECK( ean13_restored_ == expected_ean13_ );
}

int test_main( int, char* [] )
{
	barcode::ean13 ean13_( "4820024700016" );
	BOOST_CHECK( ean13_.prefix() == 4 );
	BOOST_CHECK( ean13_.country_code() == 482 );
	BOOST_CHECK( to_string( ean13_ ) == "4820024700016" );

	BOOST_CHECK( ean13_.check_sum() == 6 );
	BOOST_CHECK( ean13_.validate() );

	test_binary_symmetry( ean13_ );

	boost::uint8_t ean13_data_[] = { 55, 27, 13, 13, 27, 29, 68, 114, 114, 114, 102, 80 };
	test_data_restore( ean13_data_
		, ean13_data_ + sizeof( ean13_data_ ) / sizeof( ean13_data_[ 0 ] ) 
		, ean13_
		);

	barcode::gs1::country_code usa_code_( "USA", barcode::gs1::make_validator( 0, 139 ) );

	BOOST_CHECK( usa_code_.check_code( 0 ) );
	BOOST_CHECK( usa_code_.check_code( 138 ) );
	BOOST_CHECK( usa_code_.check_code( 139 ) );
	BOOST_CHECK( !usa_code_.check_code( 140 ) );

	barcode::gs1::country_code japan_code_( "Japan", barcode::gs1::make_validator( 
		barcode::gs1::make_validator( 450, 459 )
		, barcode::gs1::make_validator( 490, 499 ) )
		);

	BOOST_CHECK( !japan_code_.check_code( 449 ) );
	BOOST_CHECK( japan_code_.check_code( 450 ) );
	BOOST_CHECK( !japan_code_.check_code( 460 ) );
	BOOST_CHECK( japan_code_.check_code( 490 ) );

	barcode::gs1::code_ptr code_ = barcode::gs1::country_codes::all().find( ean13_.country_code() );
	BOOST_CHECK( code_ );
	BOOST_CHECK( code_->country() == "Ukraine" );

	return 0;
}
